package dao

import (
	"fmt"
	"time"
	"yundian/internel/app/helper"
	"yundian/internel/app/helper/request"
	"yundian/internel/app/helper/resphelper/placeresp"
	"yundian/internel/app/models/devices"
	"yundian/internel/app/models/devploys"
	"yundian/internel/app/models/devrule"
	"yundian/internel/app/models/devtype"
	"yundian/internel/app/models/placemodel"
	"yundian/internel/app/models/room"
	"yundian/internel/pkg/dingo"
	"yundian/internel/pkg/dingo/global"
	"yundian/internel/pkg/utils"
)

// -------------------- dao层 - 设备相关操作 -----------------------//

type DeviceDao struct {
}

func NewDeviceDao() *DeviceDao {
	return &DeviceDao{}
}

func (d *DeviceDao) GetDevicePdPassword(index int, key, typeName string) *dingo.ErrorWrap {
	pw := ``
	db := global.Orm.Table("ble_device_password bdp").Select("bdp.password")
	db.Where("bdp.index=? AND bdp.key=? AND bdp.type=?", index, key, typeName)
	db.Find(&pw)
	return dingo.ErrorIf(db.Error, pw)
}

func (d *DeviceDao) GetDeviceByUserIds(userIds []int) *dingo.ErrorWrap {
	m := devices.New()
	db := global.Orm.Table("devices d")
	db.Where("d.agent_user_id IN ?", userIds)
	db.Where("place_id=?", 0)
	db.Order("device_sn").Find(&m)
	return dingo.ErrorIf(db.Error, m)
}

// SetStewardDeviceWifi 设备绑定
func (d *DeviceDao) SetStewardDeviceWifi(param *devices.DeviceModel) *dingo.ErrorWrap {
	db := global.Orm.Table("devices").Where("device_sn=?", param.DeviceSn)
	db.Updates(map[string]interface{}{
		"place_id":   param.PlaceId,
		"place_name": param.PlaceName,
	})
	return dingo.ErrorIf(db.Error)
}

// SetStewardDevice 设备绑定
func (d *DeviceDao) SetStewardDevice(param *request.SetStewardDeviceReq) *dingo.ErrorWrap {
	db := global.Orm.Table("devices")
	if param.Id > 0 {
		db.Where("id=?", param.Id)
	} else {
		db.Where("device_sn=?", param.DeviceSn)
	}
	if db.Update("room", param.Room); db.Error != nil {
		return dingo.ErrorIf(db.Error)
	}

	if roomData := NewRoomDaoDao().SetRoomConfig(&room.Db{
		PlaceId:      param.PlaceId,
		DeviceSn:     param.DeviceSn,
		Room:         param.Room,
		Status:       param.Status,
		TypeId:       param.TypeId,
		WifiName:     param.WifiName,
		WifiPassword: param.WifiPassword,
	}); roomData.Err != nil {
		return dingo.ErrorIf(roomData.Err)
	}

	if param.WifiSync == 1 {
		db := global.Orm.Table("room").Where("place_id=? AND room<>''", param.PlaceId)
		if db.Update("wifi_password", param.WifiPassword); db.Error != nil {
			return dingo.ErrorIf(db.Error)
		}
	}

	db = global.Orm.Table("places").Where("id=?", param.PlaceId)
	db.Update("service_call", param.ServiceCall)
	return dingo.ErrorIf(db.Error)
}

// FetchStewardDeviceList 获取列表
func (d *DeviceDao) FetchStewardDeviceList(param *request.StewardDeviceListReq) *dingo.ErrorWrap {
	var (
		lst    []*request.StewardDeviceListRes
		count  int64
		limit  int = param.PageSize
		offset int = param.PageSize * (param.PageNo - 1)
	)

	fields := `d.id,d.device_sn,d.room,d.place_id,p.place_name,p.service_call,d.update_at,
	r.type_id,r.status,r.wifi_name,r.wifi_password,rt.type_name,rt.price,rt.discounts_amount`
	db := global.Orm.Table("devices d").Select(fields)
	db.Joins("LEFT JOIN places p ON d.place_id=p.id")
	db.Joins("LEFT JOIN room r ON d.place_id=r.place_id AND d.room=r.room")
	db.Joins("LEFT JOIN room_type rt ON rt.id=r.type_id")
	db.Where("d.place_id>0")

	//if param.IsAdmin != helper.TypeNumIsAdminOperator {
	//	db.Where("p.user_id=?", param.LoginUserId)
	//}
	if !helper.IsAdminAndStaff(param.IsAdmin, param.ParentId) {
		db.Where("p.user_id=?", param.LoginUserId)
	}

	if param.TypeName != "" {
		db.Where("rt.type_name LIKE ?", "%"+param.TypeName+"%")
	}
	if param.RoomStatus > 0 {
		db.Where("r.status=?", param.RoomStatus)
	}
	if param.PlaceId > 0 {
		db.Where("p.id=?", param.PlaceId)
	}
	if param.PlaceName != "" {
		PlaceStrSql := "%" + param.PlaceName + "%"
		db.Where("p.place_name LIKE ? OR p.id LIKE ?", PlaceStrSql, PlaceStrSql)
	}
	if param.RoomName != "" {
		db.Where("d.room LIKE ?", "%"+param.RoomName+"%")
	}
	if param.RoomType == 1 {
		db.Where("d.room<>?", "")
	}
	if param.RoomType == 2 {
		db.Where("d.room=?", "")
	}
	if param.DeviceSn != "" {
		db.Where("d.device_sn=?", param.DeviceSn)
	}

	db.Limit(limit).Offset(offset).Find(&lst).Limit(-1).Offset(-1).Count(&count)
	return dingo.ErrorIf(db.Error, lst, count)
}

// GetDeviceBySn 获取设备详情API
func (d *DeviceDao) GetDeviceTodaySnByCreateat() *dingo.ErrorWrap {
	m := devices.New()
	//lst := make([]*devices.DeviceModel,0)
	today := time.Now().Format("2006-01-02")
	//today := "1024YD03969"
	//fmt.Println("我是DAO当天时间为：", today)
	sql := " select * from devices where DATE_FORMAT(FROM_UNIXTIME(create_at),'%Y-%m-%d') = ? " +
		" ORDER BY device_sn DESC  LIMIT 1"

	//sql := " select * from devices where device_sn = ?"
	db := global.Orm.Raw(sql, today).Find(m)

	//fmt.Println("sql: ", sql)
	//fmt.Println("返回的结果：", m)
	return dingo.ErrorIf(db.Error, m)
}

// FetchDeviceListWithType 获取列表 (设备信息、设备类型)
func (d *DeviceDao) FetchDeviceListWithType(param *request.DeviceListReq) *dingo.ErrorWrap {
	var (
		lst   []*devices.DeviceType
		count int64
	)

	limit := param.PageSize
	offset := param.PageSize * (param.PageNo - 1)

	db := global.Orm.Debug().Table("devices")

	if param.PreSn != "" {
		db.Where("pre_sn = ?", param.PreSn)
	} // 查询条件：设备批号
	if param.SnBegin > 0 && param.SnEnd > 0 {
		db.Where("sn >= ? and sn <= ?", param.SnBegin, param.SnEnd)
	} // 查询条件：设备序号
	if param.DeviceSn != "" {
		db.Where("device_sn like ?", fmt.Sprint("%", param.DeviceSn, "%"))
	} // 查询条件：设备序列号
	if param.DeviceTypeId > 0 {
		db.Where("device_type_id = ?", param.DeviceTypeId)
	} // 查询条件：设备类型
	if param.Status > 0 {
		db.Where("state = ?", param.Status)
	} // 查询条件：状态
	if param.PlaceName != "" {
		db.Where("place_name like ?", fmt.Sprint("%", param.PlaceName, "%"))
	} //网点名称
	if param.SharedMode != "" {
		db.Where("shared_mode = ?", param.SharedMode)
	}
	if param.ProdType > 0 {
		db.Where("prod_type = ?", param.ProdType)
	}
	if param.PlaceId > 0 {
		db.Where("place_id = ?", param.PlaceId)
	} else {
		if param.LoginUserId != 2 { // loginUserId为 2 时  取所有
			placesBranchIds := NewUserDao().GetPlacesId(param.LoginUserId).Unwrap().([]int) // 查询用户ID下的所有关联门店
			userIdArr := NewUserDao().QueryChildUserIds(param.LoginUserId).Unwrap().([]int) // 查询用户ID下所有下级用户ID
			placeIdArr := NewPlaceDao().GetPlaceByIds(userIdArr).Unwrap().([]int)           // 下级用户ID 下的门店
			placesBranchIds = append(placesBranchIds, placeIdArr...)                        // 合并门店
			placesIds := utils.RemoveRepByMap(placesBranchIds)                              // 去重门店
			db.Where("place_id in (?)", placesIds)
		}
	}

	if param.IsPlaceGroup == 1 {
		db.Where("place_id>0")
		db.Group("place_id").Group("prod_type")
		db.Order("place_id DESC")
	}

	// 排序
	if param.SortField != "" && param.SortOrder == "ascend" {
		db.Order(fmt.Sprintf("%s asc", utils.String(param.SortField).SnakeCase()))
	}
	if param.SortField != "" && param.SortOrder == "descend" {
		db.Order(fmt.Sprintf("%s desc", utils.String(param.SortField).SnakeCase()))
	}
	if param.SortField == "" {
		db.Order("id DESC")
	}

	db.Limit(limit).Offset(offset).Find(&lst).Offset(-1).Limit(-1).Count(&count)
	return dingo.ErrorIf(db.Error, lst, count)
}

func (d *DeviceDao) FetchDeviceListWithTypeByUid(param *request.DeviceListReq) *dingo.ErrorWrap {
	var (
		lst   []*devices.DeviceType
		count int64
	)

	limit := param.PageSize
	offset := param.PageSize * (param.PageNo - 1)

	db := global.Orm.Debug().Table("devices")
	db.Where("agent_user_id = ?", param.LoginUserId)

	db.Limit(limit).Offset(offset).Find(&lst).Offset(-1).Limit(-1).Count(&count)
	return dingo.ErrorIf(db.Error, lst, count)
}

// 公众号商户获取设备列表，不显示所有字段,只显示部分字段
func (d *DeviceDao) LoadDeviceListWithTypeByPlace(param *request.DeviceListByPlaceReq) *dingo.ErrorWrap {
	var (
		lst   []devices.DeviceTypeByPlace
		count int64
	)

	limit := param.PageSize
	offset := param.PageSize * (param.PageNo - 1)

	db := global.Orm.Table("devices d").
		Select("d.*,t.device_name,t.device_model_id").
		Joins("left join device_type t on d.device_type_id = t.id")

	if param.DeviceSn != "" {
		db.Where("d.device_sn like ?", fmt.Sprint("%", param.DeviceSn, "%"))
	}
	if param.Status > 0 {
		db.Where("d.state = ?", param.Status)
	}
	if param.SharedMode != "" {
		db.Where("d.shared_mode = ?", param.SharedMode)
	}
	if param.PlaceId > 0 {
		db.Where("d.place_id = ?", param.PlaceId)
	} else if param.IsAdmin == helper.TypeNumIsAdminAgent && param.IsPlace != helper.TypeNumIsPlaceKa {
		// 查询代理商/商户所有下级
		userIdArr := NewUserDao().QueryChildUserIds(param.UserId).Unwrap().([]int)
		userIdArr = append(userIdArr, param.UserId)
		placeModelLst := NewPlaceDao().GetPlaceByParentIds(userIdArr).Unwrap().([]*placemodel.PlaceModel)
		placeIdArr := make([]int, 0)
		for _, placeModel := range placeModelLst {
			placeIdArr = append(placeIdArr, placeModel.Id)
		}
		db.Where("d.place_id in ?", placeIdArr)
	} else if param.IsPlace == helper.TypeNumIsPlaceKa {
		// 分公司帐号查询
		placeModelLst := NewPlaceDao().GetPlaceByBranchUserId(param.UserId).Unwrap().([]*placemodel.PlaceModel)
		placeIdArr := make([]int, 0)
		for _, placeModel := range placeModelLst {
			placeIdArr = append(placeIdArr, placeModel.Id)
		}
		db.Where("d.place_id in ?", placeIdArr)
	}
	if param.DeviceOrder != "" {
		db.Order(fmt.Sprintf("d.device_sn %s", param.DeviceOrder))
	} else {
		db.Order("d.id desc")
	}
	db.Limit(limit).Offset(offset).Find(&lst).Offset(-1).Limit(-1).Count(&count)
	return dingo.ErrorIf(db.Error, lst, count)
}

// FetchDeviceInfoWithType 获取详情 (设备信息、设备类型)
func (d *DeviceDao) FetchDeviceInfoWithType(sn string) *dingo.ErrorWrap {
	deviceType := &devices.DeviceType{}
	db := global.Orm.Table("devices d").
		Select("d.*,t.device_name,t.device_model_id").
		Joins("left join device_type t on d.device_type_id = t.id").
		Where("d.device_sn = ?", sn).
		Find(deviceType)
	return dingo.ErrorIf(db.Error, deviceType)
	// 使用原生
	//sql := "SELECT d.*,t.device_name,t.device_model_id FROM devices d " +
	//	"left join device_type t on d.device_type_id = t.id WHERE d.device_sn = ?"
	//db := global.Orm.Raw(sql, sn).Find(&deviceType)
	//return dingo.ErrorIf(db.Error, deviceType)
}

//每30分钟监控使用超时订单
func (d *DeviceDao) GetDeviceInfoWithType(sn string) *dingo.ErrorWrap {
	deviceType := &devices.DeviceType{}
	db := global.Orm.Table("devices d").
		Select("d.*,t.device_name,t.device_model_id,t.shared_mode").
		Joins("left join device_type t on d.device_type_id = t.id").
		Where("d.device_sn = ?", sn).
		Find(deviceType).Limit(1)
	return dingo.ErrorIf(db.Error, deviceType)
}

// GetDeviceInfoWithPlace 获取设备详情 (设备信息、设备类型、设备所属商户)
func (d *DeviceDao) GetDeviceInfoWithPlace(deviceSn string) *dingo.ErrorWrap {
	deviceType := &devices.DeviceWithPlace{}
	db := global.Orm.Debug().Table("devices d").
		Select(`d.*,t.device_name,t.device_model_id,p.place_name,p.url,p.banners,p.province,p.service_config,
		p.city,p.county,p.address,p.is_ad,p.hotel_id,p.project_label,p.service_call,p.is_steward,p.is_business,d.room,p.is_ad_banner,p.is_open`).
		Joins("left join device_type t on d.device_type_id = t.id").
		Joins("left join places p on d.place_id = p.id").
		Where("d.device_sn = ?", deviceSn).
		Find(deviceType)
	return dingo.ErrorIf(db.Error, deviceType)
}

// InsertDevice            新增设备
func (d *DeviceDao) InsertDevice(lst []*devices.DeviceModel) *dingo.ErrorWrap {
	//for i := 0; i < len(lst); i++ {
	//	log.Print("dao 设备整体数据为：",lst[i])
	//}
	db := global.Orm.Table("devices").Create(lst)
	return dingo.ErrorIf(db.Error, true)
}

// UpdateDeviceBySn        更新设备
func (d *DeviceDao) UpdateDeviceBySn(m *devices.DeviceModel) *dingo.ErrorWrap {
	db := global.Orm.Table("devices").Where("device_sn = ?", m.DeviceSn).Model(&m).Updates(m)
	return dingo.ErrorIf(db.Error, true)
}

func (d *DeviceDao) UpdateDeviceTypeById(id, deviceTypeId int) *dingo.ErrorWrap {
	deviceTypeInfo := NewDeviceTypeDao().GetDeviceTypeDetail(deviceTypeId).Unwrap().(*devtype.DeviceTypeModel) // 获取设备类型

	m := devices.New()
	m.DeviceTypeId = deviceTypeId
	m.DeviceTypeName = deviceTypeInfo.DeviceName
	m.FeeMode = uint8(deviceTypeInfo.FeeMode)
	db := global.Orm.Debug().Table("devices").Select("device_type_id", "device_type_name", "fee_mode").Where("id = ?", id).Updates(&m)
	return dingo.ErrorIf(db.Error, true)
}

// 修改某个网点的下的所有设备类型
func (d *DeviceDao) UpdateDeviceTypeByPlaceId(placeId, deviceTypeId int) *dingo.ErrorWrap {
	deviceTypeInfo := NewDeviceTypeDao().GetDeviceTypeDetail(deviceTypeId).Unwrap().(*devtype.DeviceTypeModel) // 获取设备类型

	m := devices.New()
	m.DeviceTypeId = deviceTypeId
	m.DeviceTypeName = deviceTypeInfo.DeviceName
	m.FeeMode = uint8(deviceTypeInfo.FeeMode)
	db := global.Orm.Debug().Table("devices").Select("device_type_id", "device_type_name", "fee_mode").Where("place_id = ?", placeId).Updates(&m)
	return dingo.ErrorIf(db.Error, true)
}

// DeleteDeviceBySn         删除设备
func (d *DeviceDao) DeleteDeviceBySn(sn string) *dingo.ErrorWrap {
	db := global.Orm.Exec("delete from devices where device_sn = ?", sn)
	return dingo.ErrorIf(db.Error, true)
}

// 删除设备
func (d *DeviceDao) DeleteDeviceById(id int) *dingo.ErrorWrap {
	db := global.Orm.Exec("delete from devices where id = ?", id)
	return dingo.ErrorIf(db.Error, true)
}

// 查询设备
func (d *DeviceDao) GetDeviceBySnAndPreSn(preSn string, sn int) *dingo.ErrorWrap {
	m := devices.New()
	db := global.Orm.Raw("select * from devices where pre_sn = ? and  sn = ?", preSn, sn).Find(&m)
	return dingo.ErrorIf(db.Error, m)
}

// 查询设备
func (d *DeviceDao) GetDeviceById(id int) *dingo.ErrorWrap {
	m := devices.New()
	db := global.Orm.Raw("select * from devices where id = ?", id).Find(&m)
	return dingo.ErrorIf(db.Error, m)
}

// 查询设备
func (d *DeviceDao) GetDeviceByDeviceSn(deviceSn string) *dingo.ErrorWrap {
	m := devices.New()
	db := global.Orm.Raw("select * from devices where device_sn=?", deviceSn).Find(&m)
	return dingo.ErrorIf(db.Error, m)
}

// 设备绑定
func (d *DeviceDao) SetDeviceBinding(param *devices.DeviceModel) *dingo.ErrorWrap {
	dbInfo := map[string]interface{}{
		"state":      2,
		"deploy_at":  time.Now(),
		"update_at":  time.Now(),
		"place_id":   param.PlaceId,
		"place_name": param.PlaceName,
		"room":       param.Room,
	}
	db := global.Orm.Table("devices").Where("device_sn=?", param.DeviceSn).Updates(dbInfo)
	return dingo.ErrorIf(db.Error)
}

// 门店设备解绑
func (d *DeviceDao) SetDeviceUnbind(param *devices.DeviceModel) *dingo.ErrorWrap {
	dbInfo := map[string]interface{}{
		"state":      1,
		"place_id":   0,
		"place_name": "",
		"room":       "",
	}
	db := global.Orm.Table("devices").Where("device_sn=?", param.DeviceSn).Updates(dbInfo)
	return dingo.ErrorIf(db.Error)
}

// 解绑，线统一回收给运营商
func (d *DeviceDao) UpdateDeviceBindStatus(id int) *dingo.ErrorWrap {
	db := global.Orm.Exec("update devices set place_id = 0,place_name = '',agent_user_id = 2,agent_user_name = '中曼(总公司)',state = 1 where id = ?", id)
	return dingo.ErrorIf(db.Error, true)
}

// UpdateDevicePwdNo 更新密码序列
func (d *DeviceDao) UpdateDevicePwdNo(sn string, no int) *dingo.ErrorWrap {
	m := devices.New()
	db := global.Orm.Model(m).Table("devices").Where("device_sn = ?", sn).Update("pwd_index", no)
	return dingo.ErrorIf(db.Error, true)
}

// 获取设备总条数
func (d *DeviceDao) GetDeviceCount() *dingo.ErrorWrap {
	var total int64
	sql := `SELECT count(*) as total FROM devices`
	db := global.Orm.Raw(sql).Find(&total)
	return dingo.ErrorIf(db.Error, total)
}

// 获取商户的设备条数
func (d *DeviceDao) GetDeviceCountByPlaceId(placeId int) *dingo.ErrorWrap {
	var total int64
	sql := `SELECT count(*) as total FROM devices where place_id = ?`
	db := global.Orm.Debug().Raw(sql, placeId).Find(&total)
	return dingo.ErrorIf(db.Error, total)
}

func (d *DeviceDao) GetDeviceCountByPlaceIds(placeIds []int) *dingo.ErrorWrap {
	var lst []placeresp.PlaceDeviceCount
	sql := `SELECT count(*) as total,place_id FROM devices where place_id in ? GROUP BY place_id`
	db := global.Orm.Debug().Raw(sql, placeIds).Find(&lst)
	return dingo.ErrorIf(db.Error, lst)
}

// 获取代理商的设备条数
func (d *DeviceDao) GetDeviceCountByAgentId(agentId int, IsAdmin, IsPlace uint8) *dingo.ErrorWrap {
	var total int64
	db := global.Orm.Table("devices d").Where("d.place_id>0")

	if IsAdmin != helper.TypeNumIsAdminOperator {
		userIdArr := NewUserDao().QueryChildUserIds(agentId).Unwrap().([]int)
		placesIdArr := NewUserDao().GetPlacesIds(agentId, userIdArr).Unwrap().([]int)
		db.Where("d.place_id in ?", placesIdArr)
	}

	db.Count(&total)
	return dingo.ErrorIf(db.Error, total)
}

// 获取代理商的设备条数
func (d *DeviceDao) GetDeviceUsedCountByAgentId(agentId int, IsAdmin, IsPlace uint8) *dingo.ErrorWrap {
	var total int64

	db := global.Orm.Table("devices d").Where("d.place_id>0 AND d.state in (2,3)")

	if IsAdmin != helper.TypeNumIsAdminOperator {
		userIdArr := NewUserDao().QueryChildUserIds(agentId).Unwrap().([]int)
		placesIdArr := NewUserDao().GetPlacesIds(agentId, userIdArr).Unwrap().([]int)
		db.Where("d.place_id in ?", placesIdArr)
	}

	db.Count(&total)
	return dingo.ErrorIf(db.Error, total)

	//var total int64
	//sql := `SELECT count(*) as total FROM devices where agent_user_id = ? and (state = 2 or state = 3)`
	//db := global.Orm.Raw(sql, agentId).Find(&total)
	//return dingo.ErrorIf(db.Error, total)
}

func (d *DeviceDao) GetDeviceCountGroupByDeviceTypeId(placeId int) *dingo.ErrorWrap {
	var lst []placeresp.PlaceDeviceCount
	sql := `select count(1) as total,place_id,place_name,device_type_id,device_type_name
from devices where place_id = ? group by device_type_id`
	db := global.Orm.Raw(sql, placeId).Find(&lst)
	return dingo.ErrorIf(db.Error, lst)
}

func (d *DeviceDao) GetDeviceCountGroupByDeviceTypeIds(placeIds []int) *dingo.ErrorWrap {
	var lst []placeresp.PlaceDeviceCount
	sql := `select count(1) as total,place_id,place_name,device_type_id,device_type_name from devices 
	where place_id IN ? group by device_type_id,place_id ORDER BY place_id,device_type_id`
	db := global.Orm.Debug().Raw(sql, placeIds).Find(&lst)
	return dingo.ErrorIf(db.Error, lst)
}

func (d *DeviceDao) GetDeviceCountGroupByProdType(placeId int) *dingo.ErrorWrap {
	var lst []placeresp.PlaceDeviceCount
	sql := `select count(1) as total,place_id,place_name,prod_type 
from devices where place_id = ? group by prod_type`
	db := global.Orm.Raw(sql, placeId).Find(&lst)
	return dingo.ErrorIf(db.Error, lst)
}

// 获取批号
func (d *DeviceDao) GetPreSn(isAdmin uint8, parentId int, loginUserId int) *dingo.ErrorWrap {
	var lst []devices.DevicePreNum

	db := global.Orm.
		Table("devices").
		Select("pre_sn,fee_mode,device_type_id").
		Where("state = 1")

	//if isAdmin == 4 {
	//	// 如果是员工登录 那agent_user_id = 上级ID
	//	db.Where("agent_user_id = ?", parentId)
	//} else {
	//	// 如果不是员工登录，就是代理商和运营商，那agent_user_id = 当前登录的ID
	//	db.Where("agent_user_id = ?", loginUserId)
	//}
	// 按pre_sn分组
	db.Group("pre_sn").Find(&lst)

	//sql := `select pre_sn,fee_mode,device_type_id from devices where state = 1 group by pre_sn`
	//db := global.Orm.Raw(sql).Find(&lst)
	return dingo.ErrorIf(db.Error, lst)
	//var (
	//	lst   []devices.DevicePreNum
	//	count int64
	//)
	//db := global.Orm.Table("devices").
	//	Select("pre_sn,fee_mode,device_type_id")
	//db.Where("state = ?", 1)
	//db.Group("pre_sn")
	//db.Find(&lst).Count(&count)
	//return dingo.ErrorIf(db.Error, lst, count)
}

// 获取商户绑定的设备类型
func (d *DeviceDao) GetPlaceBindDeviceType(placeId int) *dingo.ErrorWrap {
	var lst []*devices.DeviceTypeIdByPlace
	sql := `SELECT device_type_id FROM devices WHERE place_id = ? GROUP BY device_type_id`
	db := global.Orm.Raw(sql, placeId).Find(&lst)
	return dingo.ErrorIf(db.Error, lst)
}

// 获取设备条数
func (d *DeviceDao) GetDeviceCountByPreSn(preSn string, isAdmin uint8, parentId int, loginUserId int) *dingo.ErrorWrap {
	var total int64
	db := global.Orm.
		Table("devices").
		Select("count(*) as total").
		Where("state = 1 and pre_sn = ?", preSn)

	if isAdmin == 4 {
		// 如果是员工登录 那agent_user_id = 上级ID
		db.Where("agent_user_id = ?", parentId)
	} else {
		// 如果不是员工登录，就是代理商和运营商，那agent_user_id = 当前登录的ID
		db.Where("agent_user_id = ?", loginUserId)
	}
	// 按pre_sn分组
	db.Find(&total)

	return dingo.ErrorIf(db.Error, total)
}

// 获取最小SN
func (d *DeviceDao) GetDeviceMinSnByPreSn(preSn string, isAdmin uint8, parentId int, loginUserId int) *dingo.ErrorWrap {
	m := devices.New()
	db := global.Orm.
		Table("devices").
		Select("device_sn,sn,pre_sn").
		Where("state = 1 and pre_sn = ?", preSn)

	if isAdmin == 4 {
		// 如果是员工登录 那agent_user_id = 上级ID
		db.Where("agent_user_id = ?", parentId)
	} else {
		// 如果不是员工登录，就是代理商和运营商，那agent_user_id = 当前登录的ID
		db.Where("agent_user_id = ?", loginUserId)
	}
	// 按pre_sn分组
	db.Order("sn asc").Limit(1).Find(&m)
	//sql := `select device_sn,sn,pre_sn from devices where state = 1 and pre_sn = ? order by sn asc limit 1`
	//db := global.Orm.Raw(sql, preSn).Find(&m)
	return dingo.ErrorIf(db.Error, m)
}

// 获取最大SN
func (d *DeviceDao) GetDeviceMaxSnByPreSn(preSn string, isAdmin uint8, parentId int, loginUserId int) *dingo.ErrorWrap {
	m := devices.New()
	db := global.Orm.
		Table("devices").
		Select("device_sn,sn,pre_sn").
		Where("state = 1 and pre_sn = ?", preSn)

	if isAdmin == 4 {
		// 如果是员工登录 那agent_user_id = 上级ID
		db.Where("agent_user_id = ?", parentId)
	} else {
		// 如果不是员工登录，就是代理商和运营商，那agent_user_id = 当前登录的ID
		db.Where("agent_user_id = ?", loginUserId)
	}
	// 按pre_sn分组
	db.Order("sn desc").Limit(1).Find(&m)
	//sql := `select device_sn,sn,pre_sn from devices where state = 1 and pre_sn = ? order by sn desc limit 1`
	//db := global.Orm.Raw(sql, preSn).Find(&m)
	return dingo.ErrorIf(db.Error, m)
}

// 获取sn之间所使用掉的设备标识
func (d *DeviceDao) GetDeviceUsedByPreSn(preSn string, sn int) *dingo.ErrorWrap {
	var total int64
	sql := `SELECT count(*) as total FROM devices where state != 1 and pre_sn = ? and sn = ?`
	db := global.Orm.Raw(sql, preSn, sn).Find(&total)
	return dingo.ErrorIf(db.Error, total)
}

func (d *DeviceDao) GetDeviceTypeIdByPreSn(preSn string) *dingo.ErrorWrap {
	var deviceTypeId int
	sql := `SELECT device_type_id FROM devices where pre_sn = ?`
	db := global.Orm.Raw(sql, preSn).Find(&deviceTypeId)
	return dingo.ErrorIf(db.Error, deviceTypeId)
}

// 获取维护者信息
func (d *DeviceDao) GetMaintainerName(placeId int) *dingo.ErrorWrap {
	var m placeresp.PlaceToDevice
	sql := `select u.name as maintainerName,p.id as place_id,p.place_name,p.maintainer_id
from users u inner join places p on u.id = p.maintainer_id where p.id = ?`
	db := global.Orm.Raw(sql, placeId).Find(&m)
	return dingo.ErrorIf(db.Error, m)
}

// -------------------- dao层 - 设备类型相关操作 -----------------------//

type DeviceTypeDao struct {
}

func NewDeviceTypeDao() *DeviceTypeDao {
	return &DeviceTypeDao{}
}

// FetchDeviceTypeList 获取设备类型列表
func (d *DeviceTypeDao) FetchDeviceTypeList(param *request.DeviceTypeListReq) *dingo.ErrorWrap {
	var (
		lst   []*devtype.DeviceTypeModel
		count int64
	)

	limit := param.PageSize
	offset := param.PageSize * (param.PageNo - 1)

	db := global.Orm.Table("device_type")

	if param.DeviceName != "" { //网点名称
		db.Where("device_name like ?", fmt.Sprint("%", param.DeviceName, "%"))
	}

	// 排序
	if param.SortField != "" && param.SortOrder == "ascend" {
		db.Order(fmt.Sprintf("%s asc", utils.String(param.SortField).SnakeCase()))
	}
	if param.SortField != "" && param.SortOrder == "descend" {
		db.Order(fmt.Sprintf("%s desc", utils.String(param.SortField).SnakeCase()))
	}

	db.Limit(limit).Offset(offset).Find(&lst).Offset(-1).Limit(-1).Count(&count)
	return dingo.ErrorIf(db.Error, lst, count)
}

// InsertDevType 新增设备类型
func (d *DeviceTypeDao) InsertDevType(m *devtype.DeviceTypeModel) *dingo.ErrorWrap {
	db := global.Orm.Table("device_type").Create(m)
	return dingo.ErrorIf(db.Error, true)
}

// UpdateDevType 更新设备类型
func (d *DeviceTypeDao) UpdateDevType(m *devtype.DeviceTypeModel) *dingo.ErrorWrap {
	db := global.Orm.Table("device_type").Model(&m).Updates(m)
	return dingo.ErrorIf(db.Error, true)
}

// UpdateDeviceTypeStatus 更新设备类型状态
func (d *DeviceTypeDao) UpdateDeviceTypeStatus(id int, status int8) *dingo.ErrorWrap {
	sql := "update device_type set status = ? where id = ?"
	db := global.Orm.Exec(sql, status, id)
	return dingo.ErrorIf(db.Error, true)
}

// DeleteDeviceType 删除设备类型
func (d *DeviceTypeDao) DeleteDeviceType(id int) *dingo.ErrorWrap {
	db := global.Orm.Exec("delete from device_type where id = ?", id)
	global.Orm.Exec("delete from device_rule where type_id = ?", id) // 删除设备类型所对应的设备规则
	return dingo.ErrorIf(db.Error, true)
}

// 获取设备类型详情
func (d *DeviceTypeDao) GetDeviceTypeDetail(id int) *dingo.ErrorWrap {
	m := devtype.New()
	db := global.Orm.Debug().Raw("select * from device_type where id = ?", id).Find(&m)
	return dingo.ErrorIf(db.Error, m)
}

// -------------------- dao层 - 设备规则相关操作 -----------------------//

type DeviceRuleDao struct {
}

func NewDeviceRuleDao() *DeviceRuleDao {
	return &DeviceRuleDao{}
}

// GetRuleInfoByMealNum 获取详情  设备规则信息
func (d *DeviceRuleDao) GetRuleInfoByMealNum(typeId int, setMealNum int8) *dingo.ErrorWrap {
	m := devrule.New()
	sql := "select * from device_rule " +
		" where type_id = ? and set_meal_num = ?"
	db := global.Orm.Raw(sql, typeId, setMealNum).Find(&m)
	return dingo.ErrorIf(db.Error, m)
}

// InsertDevRule 新增设备规则
func (d *DeviceRuleDao) InsertDevRule(m *devrule.DeviceRulesModel) *dingo.ErrorWrap {
	db := global.Orm.Table("device_rule").Create(m)
	return dingo.ErrorIf(db.Error, true)
}

func (d *DeviceRuleDao) UpdateDevRule(m *devrule.DeviceRulesModel) *dingo.ErrorWrap {
	db := global.Orm.Table("device_rule").Model(&m).Updates(m)
	return dingo.ErrorIf(db.Error, true)
}

func (d *DeviceRuleDao) InsertDevDraw(m *devploys.DevicePloysModel) *dingo.ErrorWrap {
	db := global.Orm.Table("device_ploys").Create(m)
	return dingo.ErrorIf(db.Error, true)
}

func (d *DeviceRuleDao) UpdateDevDraw(m *devploys.DevicePloysModel) *dingo.ErrorWrap {
	db := global.Orm.Table("device_ploys").Model(&m).Updates(m)
	return dingo.ErrorIf(db.Error, true)
}

// GetRuleList 查询规则信息列表
func (d *DeviceRuleDao) GetRuleList(typeId int) *dingo.ErrorWrap {
	var lst []*devrule.DeviceRulesModel
	sql := "select * from device_rule " +
		" where type_id = ?"
	db := global.Orm.Raw(sql, typeId).Find(&lst)
	return dingo.ErrorIf(db.Error, lst)
}

func (d *DeviceRuleDao) GetDrawList(typeId int) *dingo.ErrorWrap {
	var lst devploys.DevicePloysModel
	sql := `select * from device_ploys where type_id = ?`
	db := global.Orm.Raw(sql, typeId).Find(&lst)
	return dingo.ErrorIf(db.Error, lst)
}

// GetDeviceTotalByType 统计和种类型设备
func (d *DeviceDao) GetDeviceTotalByType() *dingo.ErrorWrap {
	var (
		lst []devices.DeviceTotal
	)
	//sql := "SELECT t.device_type_id,count(1) AS deviceTotal from devices t where t.state <> 1 GROUP BY t.device_type_id"
	sql := `SELECT device_type_name,shared_mode,device_type_id,count(1) AS deviceTotal 
from devices t where state <> 1 GROUP BY device_type_id`
	db := global.Orm.Raw(sql).Find(&lst)
	return dingo.ErrorIf(db.Error, lst)
}

// GetUsedDeviceTotal 统计正在使用中的设备
func (d *DeviceDao) GetUsedDeviceTotal() *dingo.ErrorWrap {
	var usedDevice int64
	sql := "SELECT count(1) from devices where state = 3"
	db := global.Orm.Raw(sql).Find(&usedDevice)

	//println("结果的值为：", usedDevice)
	return dingo.ErrorIf(db.Error, usedDevice)
}

// 已部署密码线统计
func (d *DeviceDao) GetDeployDeviceTotal() *dingo.ErrorWrap {
	var total int64
	sql := "SELECT count(1) from devices where state != 1"
	db := global.Orm.Raw(sql).Find(&total)

	return dingo.ErrorIf(db.Error, total)
}

//------------代理商层级操作

// GetDeviceCountChild 获取代理设备总条数
func (d *DeviceDao) GetDeviceCountChild(userIds []int) *dingo.ErrorWrap {
	placeIdArr := NewPlaceDao().GetPlaceByIds(userIds).Unwrap().([]int)
	var total int64
	sql := `SELECT count(*) as total FROM devices where place_id in (?)`
	db := global.Orm.Debug().Raw(sql, placeIdArr).Find(&total)
	return dingo.ErrorIf(db.Error, total)
}

// GetUsedDeviceTotalChild 统计正在使用中的设备
func (d *DeviceDao) GetUsedDeviceTotalChild(userIds []int) *dingo.ErrorWrap {
	placeIdArr := NewPlaceDao().GetPlaceByIds(userIds).Unwrap().([]int)
	var usedDevice int64
	sql := "SELECT count(1) from devices where state = 3 AND place_id in (?)"
	db := global.Orm.Raw(sql, placeIdArr).Find(&usedDevice)

	//println("结果的值为：", usedDevice)
	return dingo.ErrorIf(db.Error, usedDevice)
}

// GetDeployDeviceTotalChild 已部署密码线统计
func (d *DeviceDao) GetDeployDeviceTotalChild(userIds []int) *dingo.ErrorWrap {
	placeIdArr := NewPlaceDao().GetPlaceByIds(userIds).Unwrap().([]int)
	var total int64
	sql := "SELECT count(id) from devices where state != 1 AND place_id in (?)"
	db := global.Orm.Raw(sql, placeIdArr).Find(&total)

	return dingo.ErrorIf(db.Error, total)
}

// GetDeviceTotalByTypeChild 统计和种类型设备
func (d *DeviceDao) GetDeviceTotalByTypeChild(userIds []int) *dingo.ErrorWrap {
	var (
		lst []devices.DeviceTotal
	)
	placeIdArr := NewPlaceDao().GetPlaceByIds(userIds).Unwrap().([]int)
	//sql := "SELECT t.device_type_id,count(1) AS deviceTotal from devices t where t.state <> 1 GROUP BY t.device_type_id"
	sql := `SELECT device_type_name,shared_mode,device_type_id,count(1) AS deviceTotal 
from devices t where state <> 1 and place_id in (?) GROUP BY device_type_id`
	db := global.Orm.Raw(sql, placeIdArr).Find(&lst)
	return dingo.ErrorIf(db.Error, lst)
}

// -------分公司
func (d *DeviceDao) GetDeviceCountPlaces(placesIds []int) *dingo.ErrorWrap {
	var total int64
	sql := `SELECT count(*) as total FROM devices where place_id in (?)`
	db := global.Orm.Raw(sql, placesIds).Find(&total)
	return dingo.ErrorIf(db.Error, total)
}

// GetUsedDeviceTotalPlaces 统计正在使用中的设备
func (d *DeviceDao) GetUsedDeviceTotalPlaces(placesIds []int) *dingo.ErrorWrap {
	var usedDevice int64
	sql := "SELECT count(1) from devices where state = 3 AND place_id in (?)"
	db := global.Orm.Raw(sql, placesIds).Find(&usedDevice)

	//println("结果的值为：", usedDevice)
	return dingo.ErrorIf(db.Error, usedDevice)
}

// GetUsedDeviceTotalOrderPlaces 统计正在使用中的设备,通过订单统计
func (d *DeviceDao) GetUsedDeviceTotalOrderPlaces(userId int, isAdmin, isDraw uint8) *dingo.ErrorWrap {
	var usedDevice int64

	db := global.Orm.Debug().Table("orders o").Select("COUNT(1) total")
	db.Joins("LEFT JOIN orders_user_relevancy our ON o.trade_no=our.trade_no")
	db.Where("our.user_id=? AND o.state=?", userId, helper.TypeNumOrderStatusService)

	if isAdmin != helper.TypeNumIsAdminOperator {
		//if isDraw != helper.TypeNumIsDrawOpen {
		//	db.Where("o.is_draw<>? or o.agent_user_id=?", helper.TypeNumIsDrawOpen, userId)
		//} else {
		//	db.Where("o.is_draw<>? or (o.is_draw=? and o.agent_user_id=?)", helper.TypeNumIsDrawOpen, helper.TypeNumIsDrawOpen, userId)
		//}
		db.Where("o.is_draw<>? or (o.is_draw=? and o.agent_user_id=?)", helper.TypeNumIsDrawOpen, helper.TypeNumIsDrawOpen, userId)
		db.Where("o.is_tianhai = 0")
	}
	db.Find(&usedDevice)
	return dingo.ErrorIf(db.Error, usedDevice)
}

// GetDeployDeviceTotalPlaces 已部署密码线统计
func (d *DeviceDao) GetDeployDeviceTotalPlaces(placesIds []int) *dingo.ErrorWrap {
	var total int64
	sql := "SELECT count(1) from devices where state != 1 AND place_id in (?)"
	db := global.Orm.Raw(sql, placesIds).Find(&total)

	return dingo.ErrorIf(db.Error, total)
}

// GetDeviceTotalByTypePlaces 统计和种类型设备
func (d *DeviceDao) GetDeviceTotalByTypePlaces(placesIds []int) *dingo.ErrorWrap {
	var (
		lst []devices.DeviceTotal
	)
	//sql := "SELECT t.device_type_id,count(1) AS deviceTotal from devices t where t.state <> 1 GROUP BY t.device_type_id"
	sql := `SELECT device_type_name,shared_mode,device_type_id,count(1) AS deviceTotal 
from devices t where state <> 1 and place_id in (?) GROUP BY device_type_id`
	db := global.Orm.Raw(sql, placesIds).Find(&lst)
	return dingo.ErrorIf(db.Error, lst)
}

// 获取商户的设备条数
func (d *DeviceDao) GetDeviceCountByPlaceIdArr(placeIds []int) *dingo.ErrorWrap {
	var deviceCountPlaceIds []placeresp.DeviceCountPlaceIdsModel
	sql := `SELECT count(id) as total,place_id FROM devices where place_id in (?) GROUP BY place_id`
	db := global.Orm.Debug().Raw(sql, placeIds).Find(&deviceCountPlaceIds)
	return dingo.ErrorIf(db.Error, deviceCountPlaceIds)
}

// 设备导出列表
func (d *DeviceDao) DeviceExportList(param *request.DeviceListReq) *dingo.ErrorWrap {
	var (
		lst   []*devices.DeviceExportModel
		count int64
	)

	limit := param.PageSize
	offset := param.PageSize * (param.PageNo - 1)

	db := global.Orm.Debug().Table("devices d").
		Select("d.device_sn,d.device_type_name,d.pre_sn,d.state,d.create_at")
	//Where("d.place_id>0")

	if param.PreSn != "" { // 查询条件：设备批号
		db.Where("d.pre_sn = ?", param.PreSn)
	}
	if param.SnBegin > 0 && param.SnEnd > 0 { // 查询条件：设备序号
		db.Where("d.sn >= ? and d.sn <= ?", param.SnBegin, param.SnEnd)
	}
	if param.DeviceSn != "" { // 查询条件：设备序列号
		db.Where("d.device_sn = ?", param.DeviceSn)
	}
	if param.DeviceTypeId > 0 { // 查询条件：设备类型
		db.Where("d.device_type_id = ?", param.DeviceTypeId)
	}
	if param.Status > 0 { // 查询条件：状态
		db.Where("d.state = ?", param.Status)
	}
	if param.PlaceName != "" { //网点名称
		db.Where("d.place_name like ?", fmt.Sprint("%", param.PlaceName, "%"))
	}
	if param.SharedMode != "" {
		db.Where("d.shared_mode = ?", param.SharedMode)
	}
	if param.PlaceId > 0 {
		db.Where("d.place_id = ?", param.PlaceId)
	}

	if param.MaintainerId > 0 { //维护者

		// 获取维护者所维护的商户ID
		placeModelLst := NewPlaceDao().GetPlaceListByMaintainerId(param.MaintainerId).Unwrap().([]*placemodel.PlaceModel)
		placeIdArr := make([]int, 0)
		//log.Println("placeModelLst 数组长度：", len(placeModelLst))
		for _, placeModel := range placeModelLst {
			//fmt.Println("placeId: ",placeModel.Id)
			placeIdArr = append(placeIdArr, placeModel.Id)
		}
		db.Where("d.place_id in ?", placeIdArr)
	}

	//当前账号登录是代理商或是合伙人
	if param.IsAdmin == helper.TypeNumIsAdminAgent && param.IsPlace != helper.TypeNumIsPlaceKa {
		// 获取某个用户下的所有代理商用户ID
		// 查询代理商所有下级
		userIdArr := NewUserDao().QueryChildUserIds(param.LoginUserId).Unwrap().([]int)
		userIdArr = append(userIdArr, param.LoginUserId)
		placeModelLst := NewPlaceDao().GetPlaceByParentIds(userIdArr).Unwrap().([]*placemodel.PlaceModel)
		placeIdArr := make([]int, 0)
		for _, placeModel := range placeModelLst {
			placeIdArr = append(placeIdArr, placeModel.Id)
		}
		db.Where("d.place_id in ?", placeIdArr)
	}

	// 分公司帐号查询
	if param.IsPlace == helper.TypeNumIsPlaceKa {
		db.Joins("left join places p on d.place_id = p.id")
		placesIdArr := NewUserDao().GetPlacesId(param.LoginUserId).Unwrap().([]int)
		userIdArr := NewUserDao().QueryChildUserIds(param.LoginUserId).Unwrap().([]int)
		db.Where("(p.id in (?) or p.user_id in (?))", placesIdArr, userIdArr)
	}

	// 通过代理商条件查询 先放一放,后期在加

	// 排序

	if param.SortField != "" && param.SortOrder == "ascend" {
		db.Order(fmt.Sprintf("d.%s asc", utils.String(param.SortField).SnakeCase()))
	}
	if param.SortField != "" && param.SortOrder == "descend" {
		db.Order(fmt.Sprintf("d.%s desc", utils.String(param.SortField).SnakeCase()))
	}
	if param.SortField == "" {
		db.Order("d.id desc, d.device_sn desc")
	}

	db.Limit(limit).Offset(offset).Find(&lst).Offset(-1).Limit(-1).Count(&count)
	return dingo.ErrorIf(db.Error, lst, count)
}

//按sn 区间查询设备
func (d *DeviceDao) GetDeviceBySnInterval(beginSn, endSn int, preSn string) *dingo.ErrorWrap {
	var deviceSnInterval []devices.DeviceBySnIntervalModel
	sql := `SELECT sn,device_sn FROM devices where sn >= ?  and sn <= ? and pre_sn = ?`
	db := global.Orm.Debug().Raw(sql, beginSn, endSn, preSn).Find(&deviceSnInterval)
	return dingo.ErrorIf(db.Error, deviceSnInterval)
}

//查询设备是否绑定
func (d *DeviceDao) GetDeviceIsBing(beginSn, endSn int, preSn string) *dingo.ErrorWrap {
	var deviceCountPlaceIds []devices.DeviceIsBingModel
	sql := `SELECT sn,count(id) as total FROM devices where sn >= ?  and sn <= ? and pre_sn = ? and state != 1 GROUP BY device_sn`
	db := global.Orm.Debug().Raw(sql, beginSn, endSn, preSn).Find(&deviceCountPlaceIds)
	return dingo.ErrorIf(db.Error, deviceCountPlaceIds)
}

// 获取商户有产设备条数
func (d *DeviceDao) GetActiveDevCount(placeIds []int, startTime, endTime int) *dingo.ErrorWrap {
	//t := time.Unix(timeStamp, 0)
	//dateStr := t.Format("2006-01-02")
	//查询最大时间和最小时间
	activeDeviceTime := devices.ActiveDeviceTime{}
	if startTime == 0 && endTime == 0 {

		sqlTime := `SELECT max(create_at) as max_time,min(create_at) as min_time FROM orders`
		global.Orm.Debug().Raw(sqlTime).Find(&activeDeviceTime)
		startTime = activeDeviceTime.MaxTime
		endTime = activeDeviceTime.MinTime
	}
	startTimeStr := time.Unix(int64(startTime), 0).Format("2006-01-02")
	endTimeStr := time.Unix(int64(endTime), 0).Format("2006-01-02")

	var activeDeviceCount []devices.ActiveDeviceCount
	sql := `select count(deviceSn) as total ,date,place_id from 
(SELECT device_sn as deviceSn,DATE_FORMAT(FROM_UNIXTIME(create_at),'%Y-%m-%d') as date ,place_id FROM orders where is_draw = 0 and place_id in (?) 
and DATE_FORMAT(FROM_UNIXTIME(create_at),'%Y-%m-%d') <=  ? 
and DATE_FORMAT(FROM_UNIXTIME(create_at),'%Y-%m-%d') >=  ?  
group by DATE_FORMAT( FROM_UNIXTIME( create_at ), '%Y-%m-%d' ), device_sn) as a
 GROUP BY place_id,date`
	db := global.Orm.Debug().Raw(sql, placeIds, startTimeStr, endTimeStr).Find(&activeDeviceCount)
	return dingo.ErrorIf(db.Error, activeDeviceCount)
}

// GetUsedDeviceTotalPlaces 统计正在使用中的设备
func (d *DeviceDao) GetUsedDeviceTotalStatistical(placesIds []int, userId int) *dingo.ErrorWrap {
	var usedDevice int64

	db := global.Orm
	//查询设备总数
	if userId == 2 {
		sql := "select count(*) from (SELECT device_sn as total FROM orders where is_draw = 0  and  state = 2 and is_tianhai = 0  group by device_sn) as a"
		db.Debug().Raw(sql).Find(&usedDevice)
	} else {
		sql := `select count(*) from 
(SELECT device_sn as total FROM orders where is_draw = 0 and place_id in (?) and  state = 2 and is_tianhai = 0  group by device_sn) as a`
		db.Debug().Raw(sql, placesIds).Find(&usedDevice)

	}
	return dingo.ErrorIf(db.Error, usedDevice)

}

// 设备与门店解绑
func (d *DeviceDao) UnBindDevicePlaceByDeviceSn(deviceSn string) *dingo.ErrorWrap {
	db := global.Orm.Exec("update devices set place_id = 0,place_name = '',state = 1 where device_sn = ?", deviceSn)
	if db.Error != nil {
		return dingo.ErrorIf(db.Error, false)
	}
	return dingo.ErrorIf(db.Error, true)
}
